package com.sskj.gateway.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sskj.common.constant.RabbitMQConstant;
import com.sskj.common.constant.RedisConstant;
import com.sskj.common.dto.DeviceShadow;
import com.sskj.common.dto.DeviceTelemetry;
import com.sskj.gateway.service.IDeviceDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class DeviceDataService implements IDeviceDataService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    public void addOrUpdateShadow(DeviceTelemetry deviceTelemetry) {
        String deviceCode = deviceTelemetry.getDeviceCode();
        String key = RedisConstant.DEVICE_SHADOW + deviceCode;

        String shadowJson  = stringRedisTemplate.opsForValue().get(key);
        DeviceShadow existingShadow = null;

        if (shadowJson != null) {
            try {
                existingShadow = objectMapper.readValue(shadowJson, DeviceShadow.class);
            } catch (JsonProcessingException e) {
                log.error("不能解析设备影子信息。异常信息:{}", e.getMessage());
            }
        }

        DeviceShadow newDeviceShadow = new DeviceShadow();
        newDeviceShadow.setDeviceCode(deviceTelemetry.getDeviceCode());
        newDeviceShadow.setTimestamp(deviceTelemetry.getTimestamp());

        // 如果存在旧的影子数据，直接COPY
        Map<String, Object> newProperties = new HashMap<>();
        if (existingShadow != null && existingShadow.getProperties() != null) {
            newProperties = existingShadow.getProperties();
        }

        // 新增影子数据进行覆盖操作，未上报的保持不变
        if (deviceTelemetry.getProperties() != null) {
            newProperties.putAll(deviceTelemetry.getProperties());
        }

        newDeviceShadow.setProperties(newProperties);

        try {
            String updateJson = objectMapper.writeValueAsString(newDeviceShadow);
            stringRedisTemplate.opsForValue().set(key, updateJson);

            // 投递设备属性信息
            amqpTemplate.convertAndSend(RabbitMQConstant.DEVICE_PROPS_QUEUE, updateJson);
        } catch (JsonProcessingException e) {
            log.error("保存影子设备异常。异常信息: {}", e.getMessage());
        }
    }

    @Override
    public void online(DeviceTelemetry deviceTelemetry) {
        try {
            String jsonData = objectMapper.writeValueAsString(deviceTelemetry);
            amqpTemplate.convertAndSend(RabbitMQConstant.DEVICE_EXCHANGE, RabbitMQConstant.DEVICE_ONLINE_ROUTEING_KEY, jsonData);
        } catch (JsonProcessingException e) {
            log.error("设备上线消息投递异常。异常信息:{}", e.getMessage());
        }
    }

    @Override
    public void offline(DeviceTelemetry deviceTelemetry) {
        try {
            String jsonData = objectMapper.writeValueAsString(deviceTelemetry);
            amqpTemplate.convertAndSend(RabbitMQConstant.DEVICE_EXCHANGE, RabbitMQConstant.DEVICE_OFFLINE_ROUTEING_KEY, jsonData);
        } catch (JsonProcessingException e) {
            log.error("设备下线消息投递异常。异常信息:{}", e.getMessage());
        }
    }
}
